package com.atguigu.gmall.realtime.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.realtime.common.GmallConfig;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.hbase.client.Connection;
import redis.clients.jedis.Jedis;

/**
 * @author Felix
 * @date 2023/9/1
 * 查询维度的工具类
 */
public class DimUtil {
    /**
     * 使用旁路缓存的方式获取维度数据
     * 旁路缓存思路：先从缓存中查询维度数据，如果在缓存中找到了要查询的维度，直接将其作为方法的返回值进行返回(缓存命中)；
     *             如果在缓存中没有查询到维度数据，发送请求到hbase中查询维度，并将查询的结果放到缓存中进行缓存，方便
     *             下次查询使用
     * 缓存产品的选型：
     *      状态：     性能很好，维护性差
     *      Redis：   性能不错，维护性好      √
     * 关于Redis的设置：
     *      key:    维度表名:主键值       例如：dim_base_trademark:1
     *      type:   String
     *      expire: 1day
     * 注意：如果维度数据发生了变化，将缓存的数据清除掉
     *
     * @param jedis         操作Redis的客户端
     * @param conn          操作hbase的客户端
     * @param nameSpace     表空间
     * @param tableName     表名
     * @param rowkey        主键
     * @return        将查询的结果封装为一个json对象
     */
    public static JSONObject getDimInfo(Jedis jedis, Connection conn,String nameSpace,String tableName,String rowkey){
        //拼接从Redis中获取维度数据的key
        String key = tableName.toLowerCase() +":" + rowkey;
        //用于封装从Redis查询的内容
        String dimJsonStr = null;
        //用于封装返回的json对象
        JSONObject dimJsonObj = null;
        //先从缓存中查询维度数据
        dimJsonStr = jedis.get(key);
        if(StringUtils.isNotEmpty(dimJsonStr)){
            System.out.println("从redis中查询"+tableName+":"+rowkey+"维度数据");
            //如果在缓存中找到了要查询的维度，直接将其作为方法的返回值进行返回(缓存命中)
            dimJsonObj = JSON.parseObject(dimJsonStr);
        }else{
            System.out.println("从hbase中查询"+tableName+":"+rowkey+"维度数据");
            // 如果在缓存中没有查询到维度数据，发送请求到hbase中查询维度
            dimJsonObj = HbaseUtil.getDimInfoFromHbase(conn,nameSpace,tableName,rowkey);
            if(dimJsonObj != null){
                // 并将查询的结果放到缓存中进行缓存，方便下次查询使用
                jedis.setex(key,3600*24,dimJsonObj.toJSONString());
            }else{
                System.out.println("~~~要查找"+tableName+"的"+rowkey+"不存在~~~");
            }
        }
        return dimJsonObj;
    }

    public static void delCached(String tableName,String rowkey){
        String key = tableName + ":" + rowkey;
        Jedis jedis = RedisUtil.getJedis();
        try {
            jedis.del(key);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(jedis != null){
                System.out.println("~~~从Redis中清除缓存后，关闭资源~~~");
                RedisUtil.closeJedis(jedis);
            }
        }
    }

    public static void main(String[] args) {
        Jedis jedis = RedisUtil.getJedis();
        Connection conn = HbaseUtil.getHbaseConnection();
        System.out.println(getDimInfo(jedis, conn, GmallConfig.HBASE_NAMESPACE, "dim_base_trademark", "20"));
        HbaseUtil.closeHbaseConnection(conn);
        RedisUtil.closeJedis(jedis);
    }
}
